Repository navigation
fix(afternote): 추억 노트 미디어 갤러리 취소가 기존 첨부를 지우지 않게 (closes 1113) [base: feat/369] - #1116
Conversation
3174280 to
eb76589
Compare
|
이 PR 은
|
갤러리 런처가 취소 결과(`uri == null`)를 "선택 없음" 으로 그대로 흘려보내, 폼 갱신 콜백이 이미 붙어 있던 첨부를 null 로 덮어썼다. 같은 파일의 촬영 경로는 진작 성공했을 때만 반영하고 있었으니(`captured && uri != null`), 어긋난 쪽은 갤러리다. 첨부만 지우는 수단은 화면에 없어 취소로 지워진 값은 되돌릴 길이 없다. 장례식에 남길 영상은 로컬 pick 과 서버 prefill 이 `videoUrl` 한 칸을 겸해, 수정 모드에서는 취소 한 번이 `MediaInput.None` 으로 이어져 서버에 저장된 영상까지 떨어뜨렸다. `onPhotoSelected`/`onVideoSelected` 를 `(String?) -> Unit` → `(String) -> Unit` 으로 좁히고, 플랫폼이 주는 `Uri?` 는 런처 람다에서 바로 접는다. 널이 흘러드는 형태를 타입이 막고, `?.let` 안에서는 수신자가 `Uri` 로 좁혀져 `"null"` 문자열이 새는 갈래도 표현되지 않는다. 인자 반공변이라 호출부의 `setMemorialPhoto`/`setMemorialVideo` (`(String?) -> Unit`)는 그대로 들어간다. 첨부를 지우는 수단 자체는 이 범위 밖이다 — 별도 이슈로 분리한다. 검증: - `:feature:afternote:presentation:testDebugUnitTest` 31건 · `ktlintCheck` · `:app:compileDebugUnitTestKotlin` 통과. - 렌더링 변경이 없어 screenshot baseline 은 건드리지 않는다. closes #1113
eb76589 to
208caed
Compare
🚧 리뷰 적체 가드 — 이 PR 을 닫습니다리뷰 적체 가드(#1136)를 기존 PR 에 소급 적용했습니다. 이 PR 을 열었을 때 @1hyok 님에게 처리하지 않은 리뷰 요청이 있었습니다.
두 리뷰 모두 이 PR 이 열린 뒤인 08:34·08:36 에 처리됐습니다. 되살리는 법밀린 리뷰는 이미 정리됐으므로 지금 바로 다시 열 수 있습니다. 브랜치와 커밋은 그대로입니다. gh pr reopen 1116 |
|
↩️ 가드 오적용으로 닫혔습니다 — 판정 기준을 "PR 을 올린 시점의 미처리" 로 잡았으나, 실제 기준은 "지금까지도 미처리인가" 입니다. @1hyok 의 현재 미처리 리뷰 요청은 0건이라 이 PR 은 대상이 아닙니다. 되돌립니다. |
Sadturtleman
left a comment
There was a problem hiding this comment.
방향과 근거에 이견 없습니다. 「취소가 사실상 유일한 삭제 경로로 쓰이고 있었다」를 별건(#1114)으로 뗀 판단, 그리고 seam 을 만들었다가 그 seam 이 새 구멍(Any?.toString())을 만든다는 이유로 되돌린 것이 특히 정확합니다 — 테스트가 지키던 게 결함 자체였다는 지적이 맞습니다.
막는 것은 하나입니다.
지적
-
[blocking] base(
feat/369)와 충돌합니다.$ git merge-tree --write-tree origin/feat/369 origin/fix/1113 CONFLICT (content): .../memorial/MemorialMediaSourceState.ktmerge-base 이후 base 가 두 커밋 전진했고 둘 다 같은 파일입니다.
da17d093e refactor(afternote): discardMemorialCapture 파라미터를 non-null 로 좁힌다 d33c4779a feat(afternote): 촬영 인텐트 발사 실패를 텔레메트리에 남긴다해소는 어렵지 않아 보입니다 — 이 PR 이 건드리는 줄(런처 람다 2개 + KDoc 2줄)과 base 가 건드린 줄(
discardMemorialCapture시그니처·onCaptureFailed배선)이 서로 다른 자리입니다. base 를 한 번 물어 주세요.
확인한 것 (문제 없음)
- 인자 반공변이라 호출부
setMemorialPhoto/setMemorialVideo((String?) -> Unit)가 좁아진(String) -> Unit자리에 그대로 들어갑니다 — 호출부 수정 0건이 맞습니다. - 촬영 경로는 이미
captured && uri != null이라 이 PR 뒤에도 두 경로의 규칙이 같아집니다. - 수정 모드에서
videoUrl이 로컬 pick 과 서버 prefill 을 겸한다는 점 때문에 취소 한 번이 서버 영상까지 떨어뜨린다는 설명, 코드에서 확인했습니다(displayPhotoUri() = pickedPhotoUri ?: photoUrl도 같은 모양). - base 인 #1112 는 방금 승인했습니다 — FileProvider authority 가 매니페스트(
${applicationId}.afternote.fileprovider)와 코드(context.packageName + ".afternote.fileprovider")에서 같은 값으로 풀리는 것,cache-path가CAPTURE_DIR과 일치하는 것까지 봤습니다.
충돌은 `rememberMemorialMediaSourceState` 시그니처 한 곳이다. base 가 들여온 `onCaptureFailed` 파라미터와 이 브랜치가 좁힌 non-null 콜백 타입이 같은 줄에 겹쳤다 — 한쪽만 남으면 촬영 실패가 다시 조용해지거나 갤러리 취소가 기존 첨부를 지운다. 파라미터는 셋 다 두고 타입은 좁힌 쪽을 쓴다.
충돌 상태에서 push 된 머지 커밋(6a9d2ed)은 `pull_request` 트리거를 놓쳤다. GitHub 이 그 시점에 `refs/pull/1116/merge` 를 만들지 못해 워크플로가 아예 생성되지 않았고, 충돌이 풀린 뒤에도 그 이벤트는 소급 발사되지 않는다(#1028). 9분간 mergeable 이 unknown 에 머물고 head 에 런 0건인 것을 확인하고 빈 커밋으로 head 를 갱신한다. 검증(6a9d2ed 트리 기준, 이 커밋은 트리 동일): - :feature:afternote:presentation:testDebugUnitTest · ktlintCheck · :app:compileDebugUnitTestKotlin 통과.
[blocking] base 충돌 — 반영했습니다 (
|
🚧 리뷰 적체 가드 — 이 PR 을 닫습니다아무도 리뷰하지 않은 PR 이 1건 남아 있습니다.
이 저장소는 아무도 응답하지 않은 PR 이 1건이라도 남아 있으면 새 PR 을 열 수 없습니다 (#1136). 각 PR 에 필요한 리뷰는 한 건입니다 — 누구든 먼저 판정을 내면 그 PR 은 모두의 목록에서 빠집니다. 승인 뒤에 올라온 변경을 다시 봐 줄 의무는 없지만, 변경요청은 작성자가 반영한 시점에 다시 리뷰어의 몫이 됩니다. 되살리는 법위 리뷰를 끝낸 뒤 이 PR 을 다시 여세요. 브랜치는 지워지지 않았고 커밋도 그대로입니다. gh pr reopen 1116리뷰보다 이 PR 이 급하면 |
CI 트리거 복구 (커밋
|
🚧 리뷰 적체 가드 — 이 PR 을 닫습니다아무도 리뷰하지 않은 PR 이 1건 남아 있습니다.
이 저장소는 아무도 응답하지 않은 PR 이 1건이라도 남아 있으면 새 PR 을 열 수 없습니다 (#1136). 각 PR 에 필요한 리뷰는 한 건입니다 — 누구든 먼저 판정을 내면 그 PR 은 모두의 목록에서 빠집니다. 승인 뒤에 올라온 변경을 다시 봐 줄 의무는 없지만, 변경요청은 작성자가 반영한 시점에 다시 리뷰어의 몫이 됩니다. 되살리는 법위 리뷰를 끝낸 뒤 이 PR 을 다시 여세요. 브랜치는 지워지지 않았고 커밋도 그대로입니다. gh pr reopen 1116리뷰보다 이 PR 이 급하면 |
Dismissed because a later approving review from another current write-capable reviewer is the repository merge decision.
갤러리 런처가 취소 결과(
uri == null)를 "선택 없음" 으로 그대로 흘려보내, 폼 갱신 콜백이 이미 붙어 있던 첨부를null로 덮어썼다. 같은 파일의 촬영 경로는 진작 성공했을 때만 반영하고 있었으니(captured && uri != null), 어긋난 쪽은 갤러리다.첨부만 지우는 수단은 화면에 없어 취소로 지워진 값은 되돌릴 길이 없다. 특히 장례식에 남길 영상은 로컬 pick 과 서버 prefill 이
videoUrl한 칸을 겸해, 수정 모드에서는 취소 한 번이videoMediaInput(null) → MediaInput.None으로 이어져 서버에 저장된 영상까지 떨어뜨렸다.pickedPhotoUridisplayPhotoUri() = pickedPhotoUri ?: photoUrl이라 예전 서버 사진으로 되돌아감videoUrl+thumbnailUrl변경
4줄이다.
onPhotoSelected/onVideoSelected를(String?) -> Unit→(String) -> Unit으로 좁힌다. 인자 반공변이라 호출부의setMemorialPhoto/setMemorialVideo((String?) -> Unit)는 그대로 들어간다.Uri?(=PickVisualMedia의 결과 타입, 취소가 곧 null)는 런처 람다에서 바로 접는다 —uri?.let { onPhotoSelected(it.toString()) }.이 조합이면 널이 흘러드는 형태를 타입이 막고,
?.let안에서는 수신자가Uri로 좁혀져uri.toString()이"null"문자열을 흘리는 갈래도 표현 자체가 안 된다.검증
:feature:afternote:presentation:testDebugUnitTest31건 ·:feature:afternote:presentation:ktlintCheck·:app:compileDebugUnitTestKotlin통과.리뷰어에게
applyMemorialGalleryPick(uri: Uri?, …)를 뽑아 유닛테스트 seam 을 만들었는데, 그 함수가 널러블을 우리 시그니처로 끌어올리는 바람에uri.toString()(=Any?.toString()) 이 컴파일되는 구멍이 새로 생겼고, 테스트는 결국 그 구멍을 지키고 있었다. 람다에서 접으면 구멍 자체가 없어지므로 함수와 테스트를 함께 뺐다. 남은 가드는 타입이고, 그건 seam 하나가 아니라 호출 지점 전부에 걸린다.feat/369(feat(afternote): 추억 노트 사진·영상 즉석 촬영 인텐트 추가 (closes 369) [base: develop] #1112) 다. 결함 자체는 그 PR 이전부터 있었지만, 지금 그 코드가 있는 파일(MemorialMediaSourceState.kt)이feat/369에만 있다. feat(afternote): 추억 노트 사진·영상 즉석 촬영 인텐트 추가 (closes 369) [base: develop] #1112 는AfternoteEditorScreen인라인이던 런처를 옮기기만 해서 이 동작을 범위 밖으로 뒀다.DocumentUploadScreen.kt)는 이미 옳게 처리하고 있어 레포 안에 선례가 있다.Closes #1113